// Memory
// (c) jimon game studio

#ifndef JEH_JEMEMORY
#define JEH_JEMEMORY

#include "Config_Engine.h"
#include "jeTypes.h"
#include "jeSingleton.h"

#ifdef JE_LINUX
#include <new>
#endif

namespace je
{
	namespace core
	{
		//! Alloc memory
		JE_ENGINE_FUNCTION_API void * JE_ENGINE_FUNCTION_CALL Alloc(je_size_t Size);

		//! Realloc memory
		JE_ENGINE_FUNCTION_API void * JE_ENGINE_FUNCTION_CALL Realloc(void * Pointer,je_size_t Size);

		//! Free memory
		JE_ENGINE_FUNCTION_API void JE_ENGINE_FUNCTION_CALL Free(void * Pointer);

		//! Add Pointer To Manager
		JE_ENGINE_FUNCTION_API void JE_ENGINE_FUNCTION_CALL AddPointer(void * Pointer,const c8 * FileName,s32 LineNum,s32 Type);

		//! Remove Pointer From Manager
		JE_ENGINE_FUNCTION_API void JE_ENGINE_FUNCTION_CALL RemovePointer(void * Pointer,const c8 * FileName,s32 LineNum,s32 Type);

		//! Grab memory manager like junknown work
		JE_ENGINE_FUNCTION_API void JE_ENGINE_FUNCTION_CALL MemoryGrab();

		//! Drop memory manager like junknown work
		JE_ENGINE_FUNCTION_API void JE_ENGINE_FUNCTION_CALL MemoryDrop();
	}
}

#ifdef JE_MEMORY_MANAGEMENT
	//! New operator
	inline void * operator new(je::je_size_t s) {return je::core::Alloc(s);}

	//! Delete operator
	inline void operator delete(void * Pointer){je::core::Free(Pointer);}

	//! New operator
	inline void * operator new[](je::je_size_t s){return je::core::Alloc(s);}

	//! Delete operator
	inline void operator delete[](void * Pointer){je::core::Free(Pointer);}

	#ifdef JE_DEBUG
		//! Define JENEW
		#define JENEW(__var,__obj) { __var = new __obj; je::core::AddPointer(__var,__FILE__,__LINE__,0);}

		//! Define JEDELETE
		#define JEDELETE(__var) {delete( __var ); je::core::RemovePointer(__var,__FILE__,__LINE__,0);}

		//! Define JENEW array
		#define JENEW_A(__var,__obj,__count) { __var = new __obj [ __count ]; je::core::AddPointer(__var,__FILE__,__LINE__,1);}

		//! Define JEDELETE array
		#define JEDELETE_A(__var) {delete[]( __var ); je::core::RemovePointer(__var,__FILE__,__LINE__,1);}
	#else
		//! Define JENEW
		#define JENEW(__var,__obj) __var = new __obj;

		//! Define JEDELETE
		#define JEDELETE(__var) delete( __var );

		//! Define JENEW array
		#define JENEW_A(__var,__obj,__count) __var = new __obj [ __count ];

		//! Define JEDELETE array
		#define JEDELETE_A(__var) delete[]( __var );
	#endif
#else
	//! Define JENEW
	#define JENEW(__var,__obj) __var = new __obj;

	//! Define JEDELETE
	#define JEDELETE(__var) delete( __var );

	//! Define JENEW array
	#define JENEW_A(__var,__obj,__count) __var = new __obj [ __count ];

	//! Define JEDELETE array
	#define JEDELETE_A(__var) delete[]( __var );
#endif

#endif
